﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Address;
using HslCommunication.Core.Net;
using HslCommunication.Reflection;

namespace HslCommunication.Profinet.Melsec
{
	/// <summary>
	/// 三菱PLC通讯类，采用UDP的协议实现，采用Qna兼容3E帧协议实现，需要在PLC侧先的以太网模块先进行配置，必须为二进制通讯<br />
	/// Mitsubishi PLC communication class is implemented using UDP protocol and Qna compatible 3E frame protocol. 
	/// The Ethernet module needs to be configured first on the PLC side, and it must be binary communication.
	/// </summary>
	/// <remarks>
	/// <inheritdoc cref="T:HslCommunication.Profinet.Melsec.MelsecMcNet" path="remarks" />
	/// </remarks>
	/// <example>
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="Usage" title="简单的短连接使用" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="Usage2" title="简单的长连接使用" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="ReadExample1" title="基本的读取示例" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="ReadExample2" title="批量读取示例" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="ReadExample3" title="随机字读取示例" />
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="ReadExample4" title="随机批量字读取示例" />
	/// </example>
	// Token: 0x02000072 RID: 114
	public class MelsecMcUdp : NetworkUdpDeviceBase
	{
		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.#ctor" />
		// Token: 0x0600094A RID: 2378 RVA: 0x00035DDA File Offset: 0x00033FDA
		public MelsecMcUdp()
		{
			base.WordLength = 1;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.#ctor(System.String,System.Int32)" />
		// Token: 0x0600094B RID: 2379 RVA: 0x00035E06 File Offset: 0x00034006
		public MelsecMcUdp(string ipAddress, int port)
		{
			base.WordLength = 1;
			this.IpAddress = ipAddress;
			this.Port = port;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.Melsec.MelsecMcNet.NetworkNumber" />
		// Token: 0x17000195 RID: 405
		// (get) Token: 0x0600094C RID: 2380 RVA: 0x00035E42 File Offset: 0x00034042
		// (set) Token: 0x0600094D RID: 2381 RVA: 0x00035E4A File Offset: 0x0003404A
		public byte NetworkNumber { get; set; } = 0;

		/// <inheritdoc cref="P:HslCommunication.Profinet.Melsec.MelsecMcNet.NetworkStationNumber" />
		// Token: 0x17000196 RID: 406
		// (get) Token: 0x0600094E RID: 2382 RVA: 0x00035E53 File Offset: 0x00034053
		// (set) Token: 0x0600094F RID: 2383 RVA: 0x00035E5B File Offset: 0x0003405B
		public byte NetworkStationNumber { get; set; } = 0;

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.McAnalysisAddress(System.String,System.UInt16)" />
		// Token: 0x06000950 RID: 2384 RVA: 0x0003299A File Offset: 0x00030B9A
		protected virtual OperateResult<McAddressData> McAnalysisAddress(string address, ushort length)
		{
			return McAddressData.ParseMelsecFrom(address, length);
		}

		/// <inheritdoc />
		// Token: 0x06000951 RID: 2385 RVA: 0x00035E64 File Offset: 0x00034064
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<McAddressData> operateResult = this.McAnalysisAddress(address, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				List<byte> list = new List<byte>();
				ushort num = 0;
				while (num < length)
				{
					ushort num2 = (ushort)Math.Min((int)(length - num), 900);
					operateResult.Content.Length = num2;
					OperateResult<byte[]> operateResult2 = this.ReadAddressData(operateResult.Content);
					bool flag2 = !operateResult2.IsSuccess;
					if (flag2)
					{
						return operateResult2;
					}
					list.AddRange(operateResult2.Content);
					num += num2;
					bool flag3 = operateResult.Content.McDataType.DataType == 0;
					if (flag3)
					{
						operateResult.Content.AddressStart += (int)num2;
					}
					else
					{
						operateResult.Content.AddressStart += (int)(num2 * 16);
					}
				}
				result = OperateResult.CreateSuccessResult<byte[]>(list.ToArray());
			}
			return result;
		}

		// Token: 0x06000952 RID: 2386 RVA: 0x00035F60 File Offset: 0x00034160
		private OperateResult<byte[]> ReadAddressData(McAddressData addressData)
		{
			byte[] mcCore = MelsecHelper.BuildReadMcCoreCommand(addressData, false);
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					result = MelsecMcNet.ExtractActualData(SoftBasic.ArrayRemoveBegin<byte>(operateResult.Content, 11), false);
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06000953 RID: 2387 RVA: 0x00035FE4 File Offset: 0x000341E4
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<McAddressData> operateResult = this.McAnalysisAddress(address, 0);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				result = this.WriteAddressData(operateResult.Content, value);
			}
			return result;
		}

		// Token: 0x06000954 RID: 2388 RVA: 0x00036024 File Offset: 0x00034224
		private OperateResult WriteAddressData(McAddressData addressData, byte[] value)
		{
			byte[] mcCore = MelsecHelper.BuildWriteWordCoreCommand(addressData, value);
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandom(System.String[])" />
		// Token: 0x06000955 RID: 2389 RVA: 0x00036090 File Offset: 0x00034290
		public OperateResult<byte[]> ReadRandom(string[] address)
		{
			McAddressData[] array = new McAddressData[address.Length];
			for (int i = 0; i < address.Length; i++)
			{
				OperateResult<McAddressData> operateResult = McAddressData.ParseMelsecFrom(address[i], 1);
				bool flag = !operateResult.IsSuccess;
				if (flag)
				{
					return OperateResult.CreateFailedResult<byte[]>(operateResult);
				}
				array[i] = operateResult.Content;
			}
			byte[] mcCore = MelsecHelper.BuildReadRandomWordCommand(array);
			OperateResult<byte[]> operateResult2 = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
			bool flag2 = !operateResult2.IsSuccess;
			if (flag2)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			OperateResult operateResult3 = MelsecMcNet.CheckResponseContent(operateResult2.Content);
			bool flag3 = !operateResult3.IsSuccess;
			if (flag3)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			return MelsecMcNet.ExtractActualData(SoftBasic.ArrayRemoveBegin<byte>(operateResult2.Content, 11), false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandom(System.String[],System.UInt16[])" />
		// Token: 0x06000956 RID: 2390 RVA: 0x00036170 File Offset: 0x00034370
		public OperateResult<byte[]> ReadRandom(string[] address, ushort[] length)
		{
			bool flag = length.Length != address.Length;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>(StringResources.Language.TwoParametersLengthIsNotSame);
			}
			else
			{
				McAddressData[] array = new McAddressData[address.Length];
				for (int i = 0; i < address.Length; i++)
				{
					OperateResult<McAddressData> operateResult = McAddressData.ParseMelsecFrom(address[i], length[i]);
					bool flag2 = !operateResult.IsSuccess;
					if (flag2)
					{
						return OperateResult.CreateFailedResult<byte[]>(operateResult);
					}
					array[i] = operateResult.Content;
				}
				byte[] mcCore = MelsecHelper.BuildReadRandomCommand(array);
				OperateResult<byte[]> operateResult2 = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
				bool flag3 = !operateResult2.IsSuccess;
				if (flag3)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult operateResult3 = MelsecMcNet.CheckResponseContent(operateResult2.Content);
					bool flag4 = !operateResult3.IsSuccess;
					if (flag4)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						result = MelsecMcNet.ExtractActualData(SoftBasic.ArrayRemoveBegin<byte>(operateResult2.Content, 11), false);
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadRandomInt16(System.String[])" />
		// Token: 0x06000957 RID: 2391 RVA: 0x00036278 File Offset: 0x00034478
		public OperateResult<short[]> ReadRandomInt16(string[] address)
		{
			OperateResult<byte[]> operateResult = this.ReadRandom(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<short[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<short[]>(operateResult);
			}
			else
			{
				result = OperateResult.CreateSuccessResult<short[]>(base.ByteTransform.TransInt16(operateResult.Content, 0, address.Length));
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06000958 RID: 2392 RVA: 0x000362C4 File Offset: 0x000344C4
		[HslMqttApi("ReadBoolArray", "")]
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<McAddressData> operateResult = this.McAnalysisAddress(address, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				byte[] mcCore = MelsecHelper.BuildReadMcCoreCommand(operateResult.Content, true);
				OperateResult<byte[]> operateResult2 = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
				}
				else
				{
					OperateResult operateResult3 = MelsecMcNet.CheckResponseContent(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
					}
					else
					{
						OperateResult<byte[]> operateResult4 = MelsecMcNet.ExtractActualData(SoftBasic.ArrayRemoveBegin<byte>(operateResult2.Content, 11), true);
						bool flag4 = !operateResult4.IsSuccess;
						if (flag4)
						{
							result = OperateResult.CreateFailedResult<bool[]>(operateResult4);
						}
						else
						{
							result = OperateResult.CreateSuccessResult<bool[]>(Enumerable.ToArray<bool>(Enumerable.Take<bool>(Enumerable.Select<byte, bool>(operateResult4.Content, (byte m) => m == 1), (int)length)));
						}
					}
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06000959 RID: 2393 RVA: 0x000363D0 File Offset: 0x000345D0
		[HslMqttApi("WriteBoolArray", "")]
		public override OperateResult Write(string address, bool[] values)
		{
			OperateResult<McAddressData> operateResult = this.McAnalysisAddress(address, 0);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				byte[] mcCore = MelsecHelper.BuildWriteBitCoreCommand(operateResult.Content, values);
				OperateResult<byte[]> operateResult2 = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(mcCore, this.NetworkNumber, this.NetworkStationNumber));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult operateResult3 = MelsecMcNet.CheckResponseContent(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteRun(System.Boolean)" />
		// Token: 0x0600095A RID: 2394 RVA: 0x00036460 File Offset: 0x00034660
		[HslMqttApi]
		public OperateResult RemoteRun()
		{
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(new byte[]
			{
				1,
				16,
				0,
				0,
				1,
				0,
				0,
				0
			}, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteStop" />
		// Token: 0x0600095B RID: 2395 RVA: 0x000364D0 File Offset: 0x000346D0
		[HslMqttApi]
		public OperateResult RemoteStop()
		{
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(new byte[]
			{
				2,
				16,
				0,
				0,
				1,
				0
			}, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.RemoteReset" />
		// Token: 0x0600095C RID: 2396 RVA: 0x00036540 File Offset: 0x00034740
		[HslMqttApi]
		public OperateResult RemoteReset()
		{
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(new byte[]
			{
				6,
				16,
				0,
				0,
				1,
				0
			}, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ReadPlcType" />
		// Token: 0x0600095D RID: 2397 RVA: 0x000365B0 File Offset: 0x000347B0
		[HslMqttApi]
		public OperateResult<string> ReadPlcType()
		{
			byte[] array = new byte[4];
			array[0] = 1;
			array[1] = 1;
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(array, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult<string> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					result = OperateResult.CreateSuccessResult<string>(Encoding.ASCII.GetString(operateResult.Content, 11, 16).TrimEnd(new char[0]));
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecMcNet.ErrorStateReset" />
		// Token: 0x0600095E RID: 2398 RVA: 0x00036648 File Offset: 0x00034848
		[HslMqttApi]
		public OperateResult ErrorStateReset()
		{
			byte[] array = new byte[4];
			array[0] = 23;
			array[1] = 22;
			OperateResult<byte[]> operateResult = this.ReadFromCoreServer(MelsecMcNet.PackMcCommand(array, this.NetworkNumber, this.NetworkStationNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult operateResult2 = MelsecMcNet.CheckResponseContent(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x0600095F RID: 2399 RVA: 0x000366B7 File Offset: 0x000348B7
		public override string ToString()
		{
			return string.Format("MelsecMcUdp[{0}:{1}]", this.IpAddress, this.Port);
		}
	}
}
